/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "libzlang_xml.h"

#define OBJ_STACK_TALL			64

#define XPATH_SEGMENT_STACK_TALL	256

#define XPATH_OUTPUT_XPATH_INNERTEXT	1
#define XPATH_OUTPUT_XNODE_INNERTEXT	2

#define STRINGTOOBJECT_OPTION_LESSSTRICT	1

#define OBJECTTOSTRING_STYLE_COMPACT		0
#define OBJECTTOSTRING_STYLE_INDENT_TAB		1

struct ZlangDirectProperty_xml
{
	int		dummy ;
} ;

struct CallbackOnXmlNodeUserData
{
	char			*xml_str ;
	struct ZlangRuntime	*rt ;
	struct ZlangObject	*obj_stack[ OBJ_STACK_TALL ] ;
	struct ZlangObject	**obj_stack_top ;
	unsigned char		is_enti_obj ;
	
	struct ZlangObject	*map_item_obj ;
	struct ZlangObject	*map_item_key_obj ;
} ;

static unsigned char IsNumber( char *num_str , int num_str_len , int32_t *num , double *fnum )
{
	char		*p = NULL ;
	int		offset ;
	int32_t		n = 0 ;
	double		f = 0.00 ;
	double		f0 = 1.00 ;
	unsigned char	has_point = 0 ;
	
	for( p = num_str , offset = 0 ; offset < num_str_len ; p++ , offset++ )
	{
		if( '0' <= (*p) && (*p) <= '9' )
		{
			if( has_point == 0 )
				n = n*10 + ((*p)-'0') ;
			else
				f0 = f0/10 + (double)((*p)-'0') , f += f0 ;
		}
		else if( (*p) == '.' )
		{
			has_point = 1 ;
			f = (double)n ;
		}
		else
		{
			return 0;
		}
	}
	
	if( has_point == 0 )
	{
		if( num )
			(*num) = n ;
		return 1;
	}
	else
	{
		if( fnum )
			(*fnum) = f ;
		return 2;
	}
}

#define UPDATE_MAP_ITEM_KEY(_new_key_) \
	if( user_data->map_item_obj && user_data->map_item_key_obj ) \
	{ \
		CallRuntimeFunction_map_UpdateKey( user_data->rt , user_data->map_item_obj , user_data->map_item_key_obj , _new_key_ ); \
		DestroyObject( user_data->rt , user_data->map_item_key_obj ); \
		\
		user_data->map_item_obj = NULL ; \
		user_data->map_item_key_obj = NULL ; \
	} \

funcCallbackOnXmlNode CallbackOnXmlNode;
int CallbackOnXmlNode( int type , char *xpath , int xpath_len , int xpath_size , char *node , int node_len , char *tag , int tag_len , char *properties , int properties_len , char *content , int content_len , void *p )
{
	struct CallbackOnXmlNodeUserData	*user_data = (struct CallbackOnXmlNodeUserData *)p ;
	
	char					obj_name[ 256 ] = "" ;
	struct ZlangObject			*child_obj = NULL ;
	struct ZlangObject			*append_obj = NULL ;
	int32_t					num ;
	double					fnum ;
	
	int					nret = 0 ;
	unsigned char				ucret = 0 ;
	
	TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "obj_stack_top depth[%ld] - type[0x%02x] xpath[%.*s] tag[%.*s] content[%.*s] - rt[%p] obj_stack[%p] obj_stack_top[%p]" , user_data->obj_stack_top-user_data->obj_stack , type , xpath_len,xpath , tag_len,tag , content_len,content , user_data->rt , user_data->obj_stack , user_data->obj_stack_top )
	
	if( xpath_len == 0 )
		return 0;
	
	if( type == FASTERXML_NODE_LEAF )
	{
		if( content_len == 4 && memcmp( content , "true" , 4 ) == 0 )
		{
			snprintf( obj_name , sizeof(obj_name)-1 , "%.*s" , tag_len,tag );
			if( user_data->is_enti_obj == 0 )
			{
				child_obj = AddPropertyInObject( user_data->rt , *(user_data->obj_stack_top) , GetBoolObjectInRuntimeObjectsHeap(user_data->rt) , obj_name ) ;
				if( child_obj == NULL )
				{
					TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "AddBoolPropertyInObject failed" )
					return -321;
				}
				
				TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "AddDoublePropertyInObject[%p][%s][%s][%.*s] in obj[%p][%s][%s]" , child_obj , GetCloneObjectName(child_obj) , GetObjectName(child_obj) , content_len,content , *(user_data->obj_stack_top) , GetCloneObjectName(*(user_data->obj_stack_top)) , GetObjectName(*(user_data->obj_stack_top)) )
			}
			else
			{
				child_obj = QueryPropertyInObjectByPropertyName( user_data->rt , *(user_data->obj_stack_top) , obj_name ) ;
				if( child_obj == NULL )
				{
					TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "property[%s] not found in obj[%s]" , obj_name , GetObjectName(*(user_data->obj_stack_top)) )
					return -322;
				}
				
				if( IsTypeOf( user_data->rt , child_obj , GetBoolObjectInRuntimeObjectsHeap(user_data->rt) ) == 0 )
				{
					TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "property[%s] type not matched" , obj_name )
					return 0;
				}
				
				TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "SetDoublePropertyInObject[%p][%s][%s][%.*s] in obj[%p][%s][%s]" , child_obj , GetCloneObjectName(child_obj) , GetObjectName(child_obj) , content_len,content , *(user_data->obj_stack_top) , GetCloneObjectName(*(user_data->obj_stack_top)) , GetObjectName(*(user_data->obj_stack_top)) )
			}
			
			nret = CallRuntimeFunction_bool_SetBoolValue( user_data->rt , child_obj , TRUE ) ;
			if( nret )
			{
				TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "CallRuntimeFunction_bool_SetBoolValue failed[%d]" , nret )
				return -322;
			}
			
			UPDATE_MAP_ITEM_KEY( child_obj )
		}
		else if( content_len == 5 && memcmp( content , "false" , 5 ) == 0 )
		{
			snprintf( obj_name , sizeof(obj_name)-1 , "%.*s" , tag_len,tag );
			if( user_data->is_enti_obj == 0 )
			{
				child_obj = AddPropertyInObject( user_data->rt , *(user_data->obj_stack_top) , GetBoolObjectInRuntimeObjectsHeap(user_data->rt) , obj_name ) ;
				if( child_obj == NULL )
				{
					TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "AddBoolPropertyInObject failed" )
					return -421;
				}
				
				TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "AddDoublePropertyInObject[%p][%s][%s][%.*s] in obj[%p][%s][%s]" , child_obj , GetCloneObjectName(child_obj) , GetObjectName(child_obj) , content_len,content , *(user_data->obj_stack_top) , GetCloneObjectName(*(user_data->obj_stack_top)) , GetObjectName(*(user_data->obj_stack_top)) )
			}
			else
			{
				child_obj = QueryPropertyInObjectByPropertyName( user_data->rt , *(user_data->obj_stack_top) , obj_name ) ;
				if( child_obj == NULL )
				{
					TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "property[%s] not found in obj[%s]" , obj_name , GetObjectName(*(user_data->obj_stack_top)) )
					return -422;
				}
				
				if( IsTypeOf( user_data->rt , child_obj , GetBoolObjectInRuntimeObjectsHeap(user_data->rt) ) == 0 )
				{
					TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "property[%s] type not matched" , obj_name )
					return 0;
				}
				
				TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "SetDoublePropertyInObject[%p][%s][%s][%.*s] in obj[%p][%s][%s]" , child_obj , GetCloneObjectName(child_obj) , GetObjectName(child_obj) , content_len,content , *(user_data->obj_stack_top) , GetCloneObjectName(*(user_data->obj_stack_top)) , GetObjectName(*(user_data->obj_stack_top)) )
			}
			
			nret = CallRuntimeFunction_bool_SetBoolValue( user_data->rt , child_obj , FALSE ) ;
			if( nret )
			{
				TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "CallRuntimeFunction_bool_SetBoolValue failed[%d]" , nret )
				return -422;
			}
			
			UPDATE_MAP_ITEM_KEY( child_obj )
		}
		else
		{
			ucret = IsNumber( content , content_len , & num , & fnum ) ;
			if( ucret == 1 )
			{
				snprintf( obj_name , sizeof(obj_name)-1 , "%.*s" , tag_len,tag );
				if( user_data->is_enti_obj == 0 )
				{
					child_obj = AddPropertyInObject( user_data->rt , *(user_data->obj_stack_top) , GetIntObjectInRuntimeObjectsHeap(user_data->rt) , obj_name ) ;
					if( child_obj == NULL )
					{
						TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "AddPropertyInObject failed" )
						return -621;
					}
					
					TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "AddIntPropertyInObject[%p][%s][%s][%.*s] in obj[%p][%s][%s]" , child_obj , GetCloneObjectName(child_obj) , GetObjectName(child_obj) , content_len,content , *(user_data->obj_stack_top) , GetCloneObjectName(*(user_data->obj_stack_top)) , GetObjectName(*(user_data->obj_stack_top)) )
				}
				else
				{
					child_obj = QueryPropertyInObjectByPropertyName( user_data->rt , *(user_data->obj_stack_top) , obj_name ) ;
					if( child_obj == NULL )
					{
						TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "property[%s] not found in obj[%s]" , obj_name , GetObjectName(*(user_data->obj_stack_top)) )
						return -622;
					}
					
					if( IsTypeOf( user_data->rt , child_obj , GetIntObjectInRuntimeObjectsHeap(user_data->rt) ) == 0 )
					{
						TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "property[%s] type not matched" , obj_name )
						return 0;
					}
					
					TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "SetIntPropertyInObject[%p][%s][%s][%.*s] in obj[%p][%s][%s]" , child_obj , GetCloneObjectName(child_obj) , GetObjectName(child_obj) , content_len,content , *(user_data->obj_stack_top) , GetCloneObjectName(*(user_data->obj_stack_top)) , GetObjectName(*(user_data->obj_stack_top)) )
				}
				
				nret = CallRuntimeFunction_int_SetIntValue( user_data->rt , child_obj , num ) ;
				if( nret )
				{
					TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "CallRuntimeFunction_int_SetIntValue failed[%d]" , nret )
					return -622;
				}
				
				UPDATE_MAP_ITEM_KEY( child_obj )
			}
			if( ucret == 2 )
			{
				snprintf( obj_name , sizeof(obj_name)-1 , "%.*s" , tag_len,tag );
				if( user_data->is_enti_obj == 0 )
				{
					child_obj = AddPropertyInObject( user_data->rt , *(user_data->obj_stack_top) , GetDoubleObjectInRuntimeObjectsHeap(user_data->rt) , obj_name ) ;
					if( child_obj == NULL )
					{
						TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "AddPropertyInObject failed" )
						return -221;
					}
					
					TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "AddDoublePropertyInObject[%p][%s][%s][%.*s] in obj[%p][%s][%s]" , child_obj , GetCloneObjectName(child_obj) , GetObjectName(child_obj) , content_len,content , *(user_data->obj_stack_top) , GetCloneObjectName(*(user_data->obj_stack_top)) , GetObjectName(*(user_data->obj_stack_top)) )
				}
				else
				{
					child_obj = QueryPropertyInObjectByPropertyName( user_data->rt , *(user_data->obj_stack_top) , obj_name ) ;
					if( child_obj == NULL )
					{
						TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "property[%s] not found in obj[%s]" , obj_name , GetObjectName(*(user_data->obj_stack_top)) )
						return -222;
					}
					
					if( IsTypeOf( user_data->rt , child_obj , GetDoubleObjectInRuntimeObjectsHeap(user_data->rt) ) == 0 )
					{
						TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "property[%s] type not matched" , obj_name )
						return 0;
					}
					
					TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "SetDoublePropertyInObject[%p][%s][%s][%.*s] in obj[%p][%s][%s]" , child_obj , GetCloneObjectName(child_obj) , GetObjectName(child_obj) , content_len,content , *(user_data->obj_stack_top) , GetCloneObjectName(*(user_data->obj_stack_top)) , GetObjectName(*(user_data->obj_stack_top)) )
				}
				
				nret = CallRuntimeFunction_double_SetDoubleValue( user_data->rt , child_obj , fnum ) ;
				if( nret )
				{
					TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "CallRuntimeFunction_double_SetDoubleValue failed[%d]" , nret )
					return -222;
				}
				
				UPDATE_MAP_ITEM_KEY( child_obj )
			}
			else
			{
				snprintf( obj_name , sizeof(obj_name)-1 , "%.*s" , tag_len,tag );
				if( user_data->is_enti_obj == 0 )
				{
					child_obj = AddPropertyInObject( user_data->rt , *(user_data->obj_stack_top) , GetStringObjectInRuntimeObjectsHeap(user_data->rt) , obj_name ) ;
					if( child_obj == NULL )
					{
						TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "AddPropertyInObject failed" )
						return -121;
					}
					
					TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "AddStringPropertyInObject[%p][%s][%s][%.*s] in obj[%p][%s][%s]" , child_obj , GetCloneObjectName(child_obj) , GetObjectName(child_obj) , content_len,content , *(user_data->obj_stack_top) , GetCloneObjectName(*(user_data->obj_stack_top)) , GetObjectName(*(user_data->obj_stack_top)) )
				}
				else
				{
					child_obj = QueryPropertyInObjectByPropertyName( user_data->rt , *(user_data->obj_stack_top) , obj_name ) ;
					if( child_obj == NULL )
					{
						TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "property[%s] not found in obj[%s]" , obj_name , GetObjectName(*(user_data->obj_stack_top)) )
						return -122;
					}
					
					if( IsTypeOf( user_data->rt , child_obj , GetStringObjectInRuntimeObjectsHeap(user_data->rt) ) == 0 )
					{
						TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "property[%s] type not matched" , obj_name )
						return 0;
					}
					
					TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "SetStringPropertyInObject[%p][%s][%s][%.*s] in obj[%p][%s][%s]" , child_obj , GetCloneObjectName(child_obj) , GetObjectName(child_obj) , content_len,content , *(user_data->obj_stack_top) , GetCloneObjectName(*(user_data->obj_stack_top)) , GetObjectName(*(user_data->obj_stack_top)) )
				}
				
				nret = CallRuntimeFunction_string_SetStringValue( user_data->rt , child_obj , content , content_len ) ;
				if( nret )
				{
					TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "CallRuntimeFunction_string_SetStringValue failed[%d]" , nret )
					return -122;
				}
				
				UPDATE_MAP_ITEM_KEY( child_obj )
			}
		}
	}
	else if( type & FASTERXML_NODE_BRANCH )
	{
		if( type & FASTERXML_NODE_ENTER )
		{
			if( (char*)(user_data->obj_stack_top+1) - (char*)(user_data->obj_stack) >= sizeof(struct ZlangObject *)*OBJ_STACK_TALL )
			{
				TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "obj stack top overflow" )
				return -211;
			}
			
			snprintf( obj_name , sizeof(obj_name)-1 , "%.*s" , tag_len,tag );
			if( user_data->obj_stack_top == user_data->obj_stack )
			{
				if( GetObjectName(*(user_data->obj_stack_top)) && STRCMP( obj_name , != , GetObjectName(*(user_data->obj_stack_top)) ) )
				{
					TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "xml root name[%s] not matched object name[%s]" , obj_name , GetObjectName(*(user_data->obj_stack_top)) )
					return -810;
				}
				
				append_obj = *(user_data->obj_stack_top) ;
			}
			else if( IsTypeOf( user_data->rt , *(user_data->obj_stack_top) , GetArrayObjectInRuntimeObjectsHeap(user_data->rt) )
				|| IsTypeOf( user_data->rt , *(user_data->obj_stack_top) , GetListObjectInRuntimeObjectsHeap(user_data->rt) )
				|| IsTypeOf( user_data->rt , *(user_data->obj_stack_top) , GetMapObjectInRuntimeObjectsHeap(user_data->rt) ) )
			{
				if( user_data->is_enti_obj == 0 )
				{
					child_obj = CloneZObject( user_data->rt , obj_name ) ;
					if( child_obj == NULL )
					{
						TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "CloneZObject failed" )
						return -811;
					}
				}
				else
				{
					struct ZlangObject	*tmp_obj = NULL ;
					
					tmp_obj = QueryObjectByObjectName( user_data->rt , obj_name ) ;
					if( tmp_obj == NULL )
					{
						TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "object[%s] not found" , obj_name )
						return -814;
					}
					
					child_obj = NULL ;
					nret = CloneObject( user_data->rt , & child_obj , GetObjectName(tmp_obj) , tmp_obj ) ;
					if( nret )
					{
						TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "CloneObject failed[%d]" , nret )
						return -815;
					}
				}
				
				if( IsTypeOf( user_data->rt , *(user_data->obj_stack_top) , GetArrayObjectInRuntimeObjectsHeap(user_data->rt) ) )
				{
					nret = CallRuntimeFunction_array_Append( user_data->rt , *(user_data->obj_stack_top) , child_obj , & append_obj ) ;
					if( nret )
					{
						TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "CallRuntimeFunction_array_Append failed" )
						DestroyObject( user_data->rt , child_obj );
						return -812;
					}
					else
					{
						TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "CallRuntimeFunction_array_Append[%p][%s][%s][%.*s] in obj[%p][%s][%s]" , append_obj , GetCloneObjectName(append_obj) , GetObjectName(append_obj) , content_len,content , *(user_data->obj_stack_top) , GetCloneObjectName(*(user_data->obj_stack_top)) , GetObjectName(*(user_data->obj_stack_top)) )
					}
				}
				else if( IsTypeOf( user_data->rt , *(user_data->obj_stack_top) , GetListObjectInRuntimeObjectsHeap(user_data->rt) ) )
				{
					nret = CallRuntimeFunction_list_AddTail( user_data->rt , *(user_data->obj_stack_top) , child_obj , & append_obj ) ;
					if( nret )
					{
						TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "CallRuntimeFunction_list_AddTail failed" )
						DestroyObject( user_data->rt , child_obj );
						return -812;
					}
					else
					{
						TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "CallRuntimeFunction_list_AddTail[%p][%s][%s][%.*s] in obj[%p][%s][%s]" , append_obj , GetCloneObjectName(append_obj) , GetObjectName(append_obj) , content_len,content , *(user_data->obj_stack_top) , GetCloneObjectName(*(user_data->obj_stack_top)) , GetObjectName(*(user_data->obj_stack_top)) )
					}
				}
				else if( IsTypeOf( user_data->rt , *(user_data->obj_stack_top) , GetMapObjectInRuntimeObjectsHeap(user_data->rt) ) )
				{
					struct ZlangObject	*key_obj = NULL ;
					
					key_obj = CloneULongObject( user_data->rt , obj_name ) ;
					if( key_obj == NULL )
					{
						TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "CloneUlongObject failed" )
						return -811;
					}
					
					nret = CallRuntimeFunction_ulong_SetULongValue( user_data->rt , key_obj , (uint64_t)key_obj ) ;
					if( nret )
					{
						TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "CallRuntimeFunction_ulong_SetULongValue failed[%d]" , nret )
						DestroyObject( user_data->rt , child_obj );
						DestroyObject( user_data->rt , key_obj );
						return -813;
					}
					
					nret = CallRuntimeFunction_map_Put( user_data->rt , *(user_data->obj_stack_top) , key_obj , child_obj , & append_obj ) ;
					if( nret )
					{
						TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "CallRuntimeFunction_map_Put failed[%d]" , nret )
						DestroyObject( user_data->rt , child_obj );
						DestroyObject( user_data->rt , key_obj );
						return -812;
					}
					else
					{
						TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "CallRuntimeFunction_map_Put[%p][%s][%s][%.*s] in obj[%p][%s][%s]" , append_obj , GetCloneObjectName(append_obj) , GetObjectName(append_obj) , content_len,content , *(user_data->obj_stack_top) , GetCloneObjectName(*(user_data->obj_stack_top)) , GetObjectName(*(user_data->obj_stack_top)) )
					}
					
					user_data->map_item_obj = *(user_data->obj_stack_top) ;
					user_data->map_item_key_obj = key_obj ;
				}
				
				DestroyObject( user_data->rt , child_obj );
			}
			else
			{
				if( user_data->is_enti_obj == 0 )
				{
					child_obj = AddPropertyInObject( user_data->rt , *(user_data->obj_stack_top) , GetZObjectInRuntimeObjectsHeap(user_data->rt) , obj_name ) ;
					if( child_obj == NULL )
					{
						TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "AddPropertyInObject failed" )
						return -813;
					}
					
					TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "AddPropertyInObject[%p][%s][%s] in obj[%p][%s][%s]" , child_obj , GetCloneObjectName(child_obj) , GetObjectName(child_obj) , *(user_data->obj_stack_top) , GetCloneObjectName(*(user_data->obj_stack_top)) , GetObjectName(*(user_data->obj_stack_top)) )
				}
				else
				{
					child_obj = QueryPropertyInObjectByPropertyName( user_data->rt , *(user_data->obj_stack_top) , obj_name ) ;
					if( child_obj == NULL )
					{
						TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "property[%s] not found in obj[%s]" , obj_name , GetObjectName(*(user_data->obj_stack_top)) )
						return -814;
					}
					
					TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "SetPropertyInObject[%p][%s][%s] in obj[%p][%s][%s]" , child_obj , GetCloneObjectName(child_obj) , GetObjectName(child_obj) , *(user_data->obj_stack_top) , GetCloneObjectName(*(user_data->obj_stack_top)) , GetObjectName(*(user_data->obj_stack_top)) )
				}
				
				append_obj = child_obj ;
			}
			
			user_data->obj_stack_top++;
			*(user_data->obj_stack_top) = append_obj ;
			TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "push branch obj[%p][%s][%s] to stack top" , *(user_data->obj_stack_top) , GetCloneObjectName(*(user_data->obj_stack_top)) , GetObjectName(*(user_data->obj_stack_top)) )
			OffsetRuntimeRecursizeDepth( user_data->rt , 1 );
		}
		else if( type & FASTERXML_NODE_LEAVE )
		{
			snprintf( obj_name , sizeof(obj_name)-1 , "%.*s" , tag_len,tag );
			if( user_data->obj_stack_top == user_data->obj_stack + 1 )
			{
				if( GetObjectName(*(user_data->obj_stack_top)) && STRCMP( obj_name , != , GetObjectName(*(user_data->obj_stack_top)) ) )
				{
					TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "xml root name[%s] not matched object name[%s]" , obj_name , GetObjectName(*(user_data->obj_stack_top-1)) )
					return -810;
				}
			}
			
			OffsetRuntimeRecursizeDepth( user_data->rt , -1 );
			TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "popup branch obj[%p][%s][%s] from stack top" , *(user_data->obj_stack_top) , GetCloneObjectName(*(user_data->obj_stack_top)) , GetObjectName(*(user_data->obj_stack_top)) )
			user_data->obj_stack_top--;
		}
		else
		{
			snprintf( obj_name , sizeof(obj_name)-1 , "%.*s" , tag_len,tag );
			if( user_data->is_enti_obj == 0 )
			{
				child_obj = AddNullPropertyInObject( user_data->rt , *(user_data->obj_stack_top) , GetStringObjectInRuntimeObjectsHeap(user_data->rt) , obj_name ) ;
				if( child_obj == NULL )
				{
					TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "AddPropertyInObject failed" )
					return -121;
				}
				
				TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "AddNullPropertyInObject[%p][%s][%s][%.*s] in obj[%p][%s][%s]" , child_obj , GetCloneObjectName(child_obj) , GetObjectName(child_obj) , content_len,content , *(user_data->obj_stack_top) , GetCloneObjectName(*(user_data->obj_stack_top)) , GetObjectName(*(user_data->obj_stack_top)) )
			}
			else
			{
				child_obj = QueryPropertyInObjectByPropertyName( user_data->rt , *(user_data->obj_stack_top) , obj_name ) ;
				if( child_obj == NULL )
				{
					TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "property[%s] not found in obj[%s]" , obj_name , GetObjectName(*(user_data->obj_stack_top)) )
					return -122;
				}
				
				nret = UnreferObject( user_data->rt , child_obj ) ;
				if( nret )
				{
					TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "UnreferObject failed[%d]" , nret )
					return -122;
				}
				
				TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "SetNullPropertyInObject[%p][%s][%s][%.*s] in obj[%p][%s][%s]" , child_obj , GetCloneObjectName(child_obj) , GetObjectName(child_obj) , content_len,content , *(user_data->obj_stack_top) , GetCloneObjectName(*(user_data->obj_stack_top)) , GetObjectName(*(user_data->obj_stack_top)) )
			}
		}
	}
	
	return 0;
}

ZlangDirectFunction_xml_StringToObject xml_StringToObject;
int xml_StringToObject( struct ZlangRuntime *rt , struct ZlangObject *obj , struct ZlangObject *s , struct ZlangObject *o )
{
	char					*xml_str = NULL ;
	int32_t					xml_str_len ;
	char					xpath[ 4096 ] = "" ;
	struct CallbackOnXmlNodeUserData	user_data ;
	
	int					nret = 0 ;
	
	CallRuntimeFunction_string_GetStringValue( rt , s , & xml_str , & xml_str_len );
	
	memset( & user_data , 0x00 , sizeof(struct CallbackOnXmlNodeUserData) );
	user_data.xml_str = xml_str ;
	user_data.rt = rt ;
	user_data.obj_stack[0] = o ;
	user_data.obj_stack_top = user_data.obj_stack ;
	user_data.is_enti_obj = 0 ;
	nret = TravelXmlBuffer( xml_str , xpath , sizeof(xpath) , CallbackOnXmlNode , & user_data ) ;
	if( nret )
	{
		return nret;
	}
	
	if( user_data.obj_stack_top != user_data.obj_stack )
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_INTERNAL , "user_data.obj_stack_top depth[%ld] after calling TravelXmlBuffer" , user_data.obj_stack_top-user_data.obj_stack )
		return ZLANG_ERROR_INTERNAL;
	}
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_xml_StringToObject_string;
int ZlangInvokeFunction_xml_StringToObject_string( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangObject		*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject		*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	int				nret = 0 ;
	
	nret = xml_StringToObject( rt , obj , in1 , out1 ) ;
	if( nret )
	{
		nret = UnreferObject( rt , out1 ) ;
		if( nret )
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "InitObject failed[%d]" , nret )
			return nret;
		}
		
		return 0;
	}
	
	return 0;
}

ZlangDirectFunction_xml_StringToObject xml_StringToEntityObject;
int xml_StringToEntityObject( struct ZlangRuntime *rt , struct ZlangObject *obj , struct ZlangObject *s , struct ZlangObject *o )
{
	char					*xml_str = NULL ;
	int32_t					xml_str_len ;
	char					xpath[ 4096 ] = "" ;
	struct CallbackOnXmlNodeUserData	user_data ;
	
	int					nret = 0 ;
	
	CallRuntimeFunction_string_GetStringValue( rt , s , & xml_str , & xml_str_len );
	
	memset( & user_data , 0x00 , sizeof(struct CallbackOnXmlNodeUserData) );
	user_data.xml_str = xml_str ;
	user_data.rt = rt ;
	user_data.obj_stack[0] = o ;
	user_data.obj_stack_top = user_data.obj_stack ;
	user_data.is_enti_obj = 1 ;
	nret = TravelXmlBuffer( xml_str , xpath , sizeof(xpath) , CallbackOnXmlNode , & user_data ) ;
	if( nret )
	{
		return nret;
	}
	
	if( user_data.obj_stack_top != user_data.obj_stack )
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_INTERNAL , "user_data.obj_stack_top depth[%ld] after calling TravelXmlBuffer" , user_data.obj_stack_top-user_data.obj_stack )
		return ZLANG_ERROR_INTERNAL;
	}
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_xml_StringToEntityObject_string_object;
int ZlangInvokeFunction_xml_StringToEntityObject_string_object( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangObject		*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject		*in2 = GetInputParameterInLocalObjectStack(rt,2) ;
	struct ZlangObject		*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	int				nret = 0 ;
	
	nret = xml_StringToEntityObject( rt , obj , in1 , in2 ) ;
	if( nret )
	{
		CallRuntimeFunction_bool_SetBoolValue( rt , out1 , FALSE );
		return 0;
	}
	
	CallRuntimeFunction_bool_SetBoolValue( rt , out1 , TRUE );
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_xml_SignSpecialHtmlTags;
int ZlangInvokeFunction_xml_SignSpecialHtmlTags( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	AddSkipHtmlTags();
	
	AddLeafHtmlTags();
	
	return 0;
}

struct XpathSegment
{
	size_t			xpath_segment_begin_offset ;
	size_t			xpath_segment_overend_offset ;
	size_t			tag_begin_offset ;
	size_t			tag_len ;
	size_t			tag_array_count ;
	size_t			tag_array_no ;
	size_t			tag_class_begin_offset ;
	size_t			tag_class_len ;
} ;

struct CallbackOnXpathUserData
{
	struct ZlangRuntime	*rt ;
	char			*xml ;
	char			*xpath ;
	size_t			depth ;
	struct XpathSegment	xpath_segment_stack[ XPATH_SEGMENT_STACK_TALL ] ;
	struct XpathSegment	*xpath_segment_stack_top ;
	struct XpathSegment	*xpath_segment ;
	int			xpath_output_flag ;
	struct ZlangObject	*out_obj ;
	
	char			*tag_class ;
	size_t			tag_class_len ;
} ;

static int DecomposeXpathSegments( struct CallbackOnXpathUserData *user_data )
{
	char			*p_xpath = NULL ;
	size_t			xpath_segment_stack_no ;
	struct XpathSegment	*xpath_segment = NULL ;
	
	/* xpath :
	/html/body/table/tr[2]/td.my_class_a/p.my_class_b[3]
	*/
	
	memset( user_data->xpath_segment_stack , 0x00 , sizeof(struct XpathSegment) * XPATH_SEGMENT_STACK_TALL );
	
	for( xpath_segment_stack_no = 0 , xpath_segment = user_data->xpath_segment_stack ; xpath_segment_stack_no < XPATH_SEGMENT_STACK_TALL ; xpath_segment_stack_no++ , xpath_segment++ )
	{
		if( xpath_segment == user_data->xpath_segment_stack )
			xpath_segment->xpath_segment_begin_offset = 0 ;
		else
			xpath_segment->xpath_segment_begin_offset = xpath_segment[-1].xpath_segment_overend_offset ;
		
		if( user_data->xpath[xpath_segment->xpath_segment_begin_offset] != '/' )
			return -11;
		
		xpath_segment->tag_begin_offset = xpath_segment->xpath_segment_begin_offset + 1 ;
		for( p_xpath=user_data->xpath+xpath_segment->tag_begin_offset , xpath_segment->tag_len=0 ; ('a'<=*(p_xpath)&&*(p_xpath)<='z') || ('A'<=*(p_xpath)&&*(p_xpath)<='Z') || ('0'<=*(p_xpath)&&*(p_xpath)<='9') || *(p_xpath)=='_' ; p_xpath++ , xpath_segment->tag_len++ )
			;
		if( xpath_segment->tag_len == 0 )
			return -21;
		if( '0' <= user_data->xpath[xpath_segment->tag_begin_offset] && user_data->xpath[xpath_segment->tag_begin_offset] <= '9' )
			return -22;
		
		if( *(p_xpath) == '.' )
		{
			p_xpath++;
			xpath_segment->tag_class_begin_offset = p_xpath - user_data->xpath ;
			for( xpath_segment->tag_class_len=0 ; ('a'<=*(p_xpath)&&*(p_xpath)<='z') || ('A'<=*(p_xpath)&&*(p_xpath)<='Z') || ('0'<=*(p_xpath)&&*(p_xpath)<='9') || *(p_xpath)=='_' ; p_xpath++ , xpath_segment->tag_class_len++ )
				;
			if( xpath_segment->tag_class_len == 0 )
				return -41;
			if( '0' <= user_data->xpath[xpath_segment->tag_class_begin_offset] && user_data->xpath[xpath_segment->tag_class_begin_offset] <= '9' )
				return -42;
		}
		
		if( *(p_xpath) == '[' )
		{
			xpath_segment->tag_array_count = 0 ;
			for( p_xpath++ ; '0'<=*(p_xpath)&&*(p_xpath)<='9' ; p_xpath++ )
				xpath_segment->tag_array_count = xpath_segment->tag_array_count * 10 + *(p_xpath)-'0' ;
			if( *(p_xpath) != ']' )
				return -31;
			
			p_xpath++;
		}
		
		if( *(p_xpath) != '/' && *(p_xpath) != '\0' )
			return -91;
		
		xpath_segment->xpath_segment_overend_offset = p_xpath - user_data->xpath ;
		
		TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "decompose : xpath_segment[%.*s] tag[%.*s] tag_array_count[%zu] tag_class[%.*s]" , (int)(xpath_segment->xpath_segment_overend_offset-xpath_segment->xpath_segment_begin_offset),user_data->xpath+xpath_segment->xpath_segment_begin_offset , (int)(xpath_segment->tag_len),user_data->xpath+xpath_segment->tag_begin_offset , xpath_segment->tag_array_count , (int)(xpath_segment->tag_class_len),user_data->xpath+xpath_segment->tag_class_begin_offset )
		
		if( user_data->xpath[xpath_segment->xpath_segment_overend_offset] == '\0' )
			break;
	}
	if( xpath_segment_stack_no >= XPATH_SEGMENT_STACK_TALL )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "xpath segment stack too depth" )
		return -101;
	}
	
	user_data->xpath_segment_stack_top = xpath_segment ;
	
	return 0;
}

#define XML_PROPERTY___CLASS	"class"

funcCallbackOnXmlProperty CallbackOnXpathProperty;
int CallbackOnXpathProperty( int type , char *xpath , int xpath_len , int xpath_size , char *propname , int propname_len , char *propvalue , int propvalue_len , char *content , int content_len , void *p )
{
	struct CallbackOnXpathUserData	*user_data = (struct CallbackOnXpathUserData *)p ;
	
	TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "XPROPERTY : depth[%ld] - type[0x%02x] xpath[%.*s] propname[%.*s] propvalue[%.*s] content[%.*s]" , user_data->depth , type , xpath_len,xpath , propname_len,propname , propvalue_len,propvalue , content_len,content )
	if( propname_len == 0 )
		return 0;
	
	if( propname_len == sizeof(XML_PROPERTY___CLASS)-1 && MEMCMP( propname , == , XML_PROPERTY___CLASS , propname_len ) && propvalue_len == user_data->xpath_segment->tag_class_len && MEMCMP( propvalue , == , user_data->xpath+user_data->xpath_segment->tag_class_begin_offset , propvalue_len ) )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "propname[%.*s][%.*s] propvalue[%.*s][%.*s] matched" , propname_len,propname , (int)(sizeof(XML_PROPERTY___CLASS)-1),XML_PROPERTY___CLASS , propvalue_len,propvalue , (int)(user_data->xpath_segment->tag_class_len),user_data->xpath+user_data->xpath_segment->tag_class_begin_offset )
		user_data->tag_class = propvalue ;
		user_data->tag_class_len = propvalue_len ;
	}
	
	return 0;
}

funcCallbackOnXmlNode CallbackOnXpath;
int CallbackOnXpath( int type , char *xpath , int xpath_len , int xpath_size , char *node , int node_len , char *tag , int tag_len , char *properties , int properties_len , char *content , int content_len , void *p )
{
	struct CallbackOnXpathUserData	*user_data = (struct CallbackOnXpathUserData *)p ;
	unsigned char			depth_match_flag = 0 ;
	unsigned char			tag_match_flag = 0 ;
	unsigned char			tag_array_match_flag = 0 ;
	unsigned char			tag_class_match_flag = 0 ;
	int				nret = 0 ;
	
	if( xpath_len == 0 )
		return 0;
	
	if( type & FASTERXML_NODE_BRANCH )
	{
		if( type & FASTERXML_NODE_LEAVE )
		{
			user_data->depth--;
			user_data->xpath_segment--;
		}
	}
	
	if( user_data->xpath_segment == user_data->xpath_segment_stack_top && user_data->depth == user_data->xpath_segment_stack_top-user_data->xpath_segment_stack )
	{
		depth_match_flag = 1 ;
		
		if( tag_len == user_data->xpath_segment->tag_len && MEMCMP( tag , == , user_data->xpath+user_data->xpath_segment->tag_begin_offset , tag_len ) )
		{
			tag_match_flag = 1 ;
			
			if( user_data->xpath_segment->tag_class_len > 0 )
			{
				user_data->tag_class = NULL ;
				nret = TravelXmlPropertiesBuffer( properties , properties_len , type , xpath , xpath_len , xpath_size , content , content_len , & CallbackOnXpathProperty , p ) ;
				if( nret )
				{
					TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "TravelXmlPropertiesBuffer failed[%d]" , nret )
					return nret;
				}
				
				if( user_data->tag_class )
					tag_class_match_flag = 1 ;
				else
					tag_class_match_flag = 0 ;
			}
			else
			{
				tag_class_match_flag = 1 ;
			}
			
			if( type == FASTERXML_NODE_LEAF || type == (FASTERXML_NODE_BRANCH|FASTERXML_NODE_ENTER) || type == FASTERXML_NODE_BRANCH )
			{
				if( user_data->xpath_segment->tag_array_count > 0 && tag_class_match_flag == 1 )
				{
					user_data->xpath_segment->tag_array_no++;
				}
			}
			
			if( user_data->xpath_segment->tag_array_count > 0 )
			{
				if( user_data->xpath_segment->tag_array_no == user_data->xpath_segment->tag_array_count )
					tag_array_match_flag = 1 ;
				else
					tag_array_match_flag = 0 ;
			}
			else
			{
				tag_array_match_flag = 1 ;
			}
		}
		else
		{
			tag_match_flag = 0 ;
		}
	}
	else
	{
		depth_match_flag = 0 ;
	}
	
	if( user_data->xpath_segment <= user_data->xpath_segment_stack_top )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "XPATH : depth[%ld][%d] - type[0x%02x] xpath[%.*s] node[%.*s%s] tag[%.*s][%d][%d] properties[%.*s][%d] content[%.*s] - xpath_segment-depth[%ld/%ld] array_no[%zu]" , user_data->depth , depth_match_flag , type , xpath_len,xpath , MIN(node_len,100),node,node_len>100?"...":"" , tag_len,tag , tag_match_flag , tag_array_match_flag , properties_len,properties , tag_class_match_flag , content_len,content , user_data->xpath_segment-user_data->xpath_segment_stack , user_data->xpath_segment_stack_top-user_data->xpath_segment_stack , user_data->xpath_segment->tag_array_no )
	}
	else
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "XPATH : depth[%ld][%d] - type[0x%02x] xpath[%.*s] node[%.*s%s] tag[%.*s][%d][%d] properties[%.*s][%d] content[%.*s] - xpath_segment-depth[%ld/%ld]" , user_data->depth , depth_match_flag , type , xpath_len,xpath , MIN(node_len,100),node,node_len>100?"...":"" , tag_len,tag , tag_match_flag , tag_array_match_flag , properties_len,properties , tag_class_match_flag , content_len,content , user_data->xpath_segment-user_data->xpath_segment_stack , user_data->xpath_segment_stack_top-user_data->xpath_segment_stack )
	}
	
	if( depth_match_flag == 1 && tag_match_flag == 1 && tag_array_match_flag == 1 && tag_class_match_flag == 1 )
	{
		char	*s = NULL ;
		int	s_len ;
		
		if( type == FASTERXML_NODE_LEAF )
		{
			if( user_data->xpath_output_flag == XPATH_OUTPUT_XPATH_INNERTEXT )
				s = content , s_len = content_len ;
			else
				s = node , s_len = node_len ;
			
			nret = CallRuntimeFunction_string_SetStringValue( user_data->rt , user_data->out_obj , s , s_len ) ;
			if( nret )
			{
				TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "CallRuntimeFunction_string_SetStringValue leaf[%.*s] to out_obj failed[%d]" , s_len,s , nret )
				return nret;
			}
			else
			{
				TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "CallRuntimeFunction_string_SetStringValue leaf[%.*s] to out_obj" , s_len,s )
			}
			
			return FASTERXML_INFO_INTERRUPT_TRAVEL;
		}
		else if( type & FASTERXML_NODE_BRANCH )
		{
			if( type & FASTERXML_NODE_ENTER )
			{
			}
			else if( type & FASTERXML_NODE_LEAVE )
			{
				if( user_data->xpath_output_flag == XPATH_OUTPUT_XPATH_INNERTEXT )
					s = content , s_len = content_len ;
				else
					s = node , s_len = node_len ;
				
				nret = CallRuntimeFunction_string_SetStringValue( user_data->rt , user_data->out_obj , s , s_len ) ;
				if( nret )
				{
					TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "CallRuntimeFunction_string_SetStringValue branch[%.*s] to out_obj failed[%d]" , s_len,s , nret )
					return nret;
				}
				else
				{
					TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "CallRuntimeFunction_string_SetStringValue branch[%.*s] to out_obj" , s_len,s )
				}
				
				return FASTERXML_INFO_INTERRUPT_TRAVEL;
			}
			else
			{
				if( user_data->xpath_output_flag == XPATH_OUTPUT_XPATH_INNERTEXT )
					s = content , s_len = content_len ;
				else
					s = node , s_len = node_len ;
				
				nret = CallRuntimeFunction_string_SetStringValue( user_data->rt , user_data->out_obj , s , s_len ) ;
				if( nret )
				{
					TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "CallRuntimeFunction_string_SetStringValue branch[%.*s] to out_obj failed[%d]" , s_len,s , nret )
					return nret;
				}
				else
				{
					TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "CallRuntimeFunction_string_SetStringValue branch[%.*s] to out_obj" , s_len,s )
				}
				
				return FASTERXML_INFO_INTERRUPT_TRAVEL;
			}
		}
	}
	
	if( type & FASTERXML_NODE_BRANCH )
	{
		if( type & FASTERXML_NODE_ENTER )
		{
			user_data->depth++;
			user_data->xpath_segment++;
		}
	}
	
	return 0;
}

static int xml_Xpath_string_string( struct ZlangRuntime *rt , struct ZlangObject *obj , char *xml_str , char *xpath_str , struct ZlangObject *out_obj , int xpath_output_flag )
{
	char				xpath_buf[ 4096 ] = "" ;
	struct CallbackOnXpathUserData	user_data ;
	int				nret = 0 ;
	
	memset( & user_data , 0x00 , sizeof(struct CallbackOnXpathUserData) );
	user_data.rt = rt ;
	user_data.xml = xml_str ;
	user_data.xpath = xpath_str ;
	user_data.depth = 0 ;
	user_data.xpath_segment = user_data.xpath_segment_stack ;
	user_data.xpath_output_flag = xpath_output_flag ;
	user_data.out_obj = out_obj ;
	
	TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "DecomposeXpathSegments[%s] ..." , user_data.xpath )
	nret = DecomposeXpathSegments( & user_data ) ;
	if( nret < 0 )
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_INVOKE_METHOD_RETURN , "DecomposeXpathSegment failed[%d]" , nret )
		UnreferObject( rt , out_obj );
		return ZLANG_ERROR_INVOKE_METHOD_RETURN;
	}
	else if( nret > 0 )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "DecomposeXpathSegment return[%d]" , nret )
		UnreferObject( rt , out_obj );
		return 0;
	}
	
	nret = TravelXmlBuffer( xml_str , xpath_buf , sizeof(xpath_buf) , CallbackOnXpath , & user_data ) ;
	if( nret )
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_INVOKE_METHOD_RETURN , "TravelXmlBuffer failed[%d]" , nret )
		UnreferObject( rt , out_obj );
		return ZLANG_ERROR_INVOKE_METHOD_RETURN;
	}
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_xml_Xpath_string_string;
int ZlangInvokeFunction_xml_Xpath_string_string( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangObject		*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject		*in2 = GetInputParameterInLocalObjectStack(rt,2) ;
	struct ZlangObject		*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	char				*xml_str = NULL ;
	char				*xpath_str = NULL ;
	
	CallRuntimeFunction_string_GetStringValue( rt , in1 , & xml_str , NULL );
	CallRuntimeFunction_string_GetStringValue( rt , in2 , & xpath_str , NULL );
	
	return xml_Xpath_string_string( rt , obj , xml_str , xpath_str , out1 , XPATH_OUTPUT_XPATH_INNERTEXT );
}

ZlangInvokeFunction ZlangInvokeFunction_xml_Xnode_string_string;
int ZlangInvokeFunction_xml_Xnode_string_string( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangObject		*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject		*in2 = GetInputParameterInLocalObjectStack(rt,2) ;
	struct ZlangObject		*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	char				*xml_str = NULL ;
	char				*xpath_str = NULL ;
	
	CallRuntimeFunction_string_GetStringValue( rt , in1 , & xml_str , NULL );
	CallRuntimeFunction_string_GetStringValue( rt , in2 , & xpath_str , NULL );
	
	return xml_Xpath_string_string( rt , obj , xml_str , xpath_str , out1 , XPATH_OUTPUT_XNODE_INNERTEXT );
}

struct CallbackOnFindAllUserData
{
	struct ZlangRuntime	*rt ;
	char			*xml ;
	char			*tag ;
	size_t			tag_len ;
	struct ZlangObject	*properties_condition_obj ;
	struct ZlangObject	*out_list_obj ;
	
	struct ZlangObject	*key_obj ;
	unsigned char		all_properties_matched ;
	struct ZlangObject	*out_map_obj ;
} ;

funcCallbackOnXmlProperty CallbackOnFindAllProperties;
int CallbackOnFindAllProperties( int type , char *xpath , int xpath_len , int xpath_size , char *propname , int propname_len , char *propvalue , int propvalue_len , char *content , int content_len , void *p )
{
	struct CallbackOnFindAllUserData	*user_data = (struct CallbackOnFindAllUserData *)p ;
	struct ZlangObject			*value_obj = NULL ;
	char					*value = NULL ;
	int32_t					value_len ;
	int					nret = 0 ;
	
	TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "XPROPERTY-FINDALL : type[0x%02x] xpath[%.*s] propname[%.*s] propvalue[%.*s] content[%.*s]" , type , xpath_len,xpath , propname_len,propname , propvalue_len,propvalue , content_len,content )
	if( propname_len == 0 )
		return 0;
	
	nret = CallRuntimeFunction_string_SetStringValue( user_data->rt , user_data->key_obj , propname , propname_len ) ;
	if( nret )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "CallRuntimeFunction_string_SetStringValue failed[%d]" , nret )
		return nret;
	}
	
	nret = CallRuntimeFunction_map_Get( user_data->rt , user_data->properties_condition_obj , user_data->key_obj , & value_obj ) ;
	if( nret )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "CallRuntimeFunction_string_SetStringValue failed[%d]" , nret )
		return nret;
	}
	
	if( value_obj )
	{
		CallRuntimeFunction_string_GetStringValue( user_data->rt , value_obj , & value , & value_len );
		if( propvalue_len == value_len && MEMCMP( propvalue , == , value , propvalue_len ) )
			;
		else
			user_data->all_properties_matched = 0 ;
	}
	
	return 0;
}

funcCallbackOnXmlProperty CallbackOnReadAllProperties;
int CallbackOnReadAllProperties( int type , char *xpath , int xpath_len , int xpath_size , char *propname , int propname_len , char *propvalue , int propvalue_len , char *content , int content_len , void *p )
{
	struct CallbackOnFindAllUserData	*user_data = (struct CallbackOnFindAllUserData *)p ;
	struct ZlangObject			*key_obj = NULL ;
	struct ZlangObject			*value_obj = NULL ;
	int					nret = 0 ;
	
	TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "XPROPERTY-READALL : type[0x%02x] xpath[%.*s] propname[%.*s] propvalue[%.*s] content[%.*s]" , type , xpath_len,xpath , propname_len,propname , propvalue_len,propvalue , content_len,content )
	if( propname_len == 0 )
		return 0;
	
	key_obj = CloneStringObject( user_data->rt , NULL ) ;
	if( key_obj == NULL )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "CloneStringObject failed[%d]" , GetRuntimeErrorNo(user_data->rt) )
		return GetRuntimeErrorNo(user_data->rt);
	}
	
	nret = CallRuntimeFunction_string_SetStringValue( user_data->rt , key_obj , propname , propname_len ) ;
	if( nret )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "CallRuntimeFunction_string_SetStringValue failed[%d]" , nret )
		DestroyObject( user_data->rt , key_obj );
		return nret;
	}
	
	value_obj = CloneStringObject( user_data->rt , NULL ) ;
	if( value_obj == NULL )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "CloneStringObject failed[%d]" , GetRuntimeErrorNo(user_data->rt) )
		DestroyObject( user_data->rt , key_obj );
		return GetRuntimeErrorNo(user_data->rt);
	}
	
	nret = CallRuntimeFunction_string_SetStringValue( user_data->rt , value_obj , propvalue , propvalue_len ) ;
	if( nret )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "CallRuntimeFunction_string_SetStringValue failed[%d]" , nret )
		DestroyObject( user_data->rt , key_obj );
		DestroyObject( user_data->rt , value_obj );
		return nret;
	}
	
	nret = CallRuntimeFunction_map_Put( user_data->rt , user_data->out_map_obj , key_obj , value_obj , NULL ) ;
	if( nret )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "CallRuntimeFunction_map_Put failed[%d]" , nret )
		DestroyObject( user_data->rt , key_obj );
		DestroyObject( user_data->rt , value_obj );
		return nret;
	}
	else
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "CallRuntimeFunction_map_Put[%.*s][%.*s] ok" , propname_len,propname , propvalue_len,propvalue )
	}
	
	DestroyObject( user_data->rt , key_obj );
	DestroyObject( user_data->rt , value_obj );
	
	return 0;
}

#define INNERTEXT	"innerText"
static int AddInnerTextToMap( char *content , int content_len , void *p )
{
	struct CallbackOnFindAllUserData	*user_data = (struct CallbackOnFindAllUserData *)p ;
	struct ZlangObject			*key_obj = NULL ;
	struct ZlangObject			*value_obj = NULL ;
	int					nret = 0 ;
	
	TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "XPROPERTY-INNERTEXT : content[%.*s]" , content_len,content )
	
	key_obj = CloneStringObject( user_data->rt , NULL ) ;
	if( key_obj == NULL )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "CloneStringObject failed[%d]" , GetRuntimeErrorNo(user_data->rt) )
		return GetRuntimeErrorNo(user_data->rt);
	}
	
	nret = CallRuntimeFunction_string_SetStringValue( user_data->rt , key_obj , INNERTEXT , sizeof(INNERTEXT)-1 ) ;
	if( nret )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "CallRuntimeFunction_string_SetStringValue failed[%d]" , nret )
		DestroyObject( user_data->rt , key_obj );
		return nret;
	}
	
	value_obj = CloneStringObject( user_data->rt , NULL ) ;
	if( value_obj == NULL )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "CloneStringObject failed[%d]" , GetRuntimeErrorNo(user_data->rt) )
		DestroyObject( user_data->rt , key_obj );
		return GetRuntimeErrorNo(user_data->rt);
	}
	
	nret = CallRuntimeFunction_string_SetStringValue( user_data->rt , value_obj , content , content_len ) ;
	if( nret )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "CallRuntimeFunction_string_SetStringValue failed[%d]" , nret )
		DestroyObject( user_data->rt , key_obj );
		DestroyObject( user_data->rt , value_obj );
		return nret;
	}
	
	nret = CallRuntimeFunction_map_Put( user_data->rt , user_data->out_map_obj , key_obj , value_obj , NULL ) ;
	if( nret )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "CallRuntimeFunction_map_Put failed[%d]" , nret )
		DestroyObject( user_data->rt , key_obj );
		DestroyObject( user_data->rt , value_obj );
		return nret;
	}
	else
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "CallRuntimeFunction_map_Put[%.*s][%.*s] ok" , (int)(sizeof(INNERTEXT)-1),INNERTEXT , content_len,content )
	}
	
	DestroyObject( user_data->rt , key_obj );
	DestroyObject( user_data->rt , value_obj );
	
	return 0;
}

funcCallbackOnXmlNode CallbackOnFindAll;
int CallbackOnFindAll( int type , char *xpath , int xpath_len , int xpath_size , char *node , int node_len , char *tag , int tag_len , char *properties , int properties_len , char *content , int content_len , void *p )
{
	struct CallbackOnFindAllUserData	*user_data = (struct CallbackOnFindAllUserData *)p ;
	unsigned char				match_flag = 0 ;
	int					nret = 0 ;
	
	if( xpath_len == 0 )
		return 0;
	
	if( type == FASTERXML_NODE_LEAF || type == (FASTERXML_NODE_BRANCH|FASTERXML_NODE_LEAVE) || type == FASTERXML_NODE_BRANCH )
	{
		if( tag_len == user_data->tag_len && MEMCMP( tag , == , user_data->tag , tag_len ) )
		{
			if( IsObjectPropertiesEntityNotNull(user_data->properties_condition_obj) )
			{
				user_data->all_properties_matched = 1 ;
				nret = TravelXmlPropertiesBuffer( properties , properties_len , type , xpath , xpath_len , xpath_size , content , content_len , & CallbackOnFindAllProperties , p ) ;
				if( nret )
				{
					TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "TravelXmlPropertiesBuffer failed[%d]" , nret )
					return nret;
				}
				
				if( user_data->all_properties_matched == 1 )
					match_flag = 1 ;
				else
					match_flag = 0 ;
			}
			else
			{
				match_flag = 1 ;
			}
		}
	}
	
	TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "XPATH : type[0x%02x] xpath[%.*s] tag[%.*s] properties[%.*s] content[%.*s] - matched[%d]" , type , xpath_len,xpath , tag_len,tag , properties_len,properties , content_len,content , match_flag )
	
	if( match_flag == 1 )
	{
		user_data->out_map_obj = CloneMapObject( user_data->rt , NULL ) ;
		if( user_data->out_map_obj == NULL )
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "CloneMapObject failed[%d]" , GetRuntimeErrorNo(user_data->rt) )
			return -1;
		}
		
		nret = TravelXmlPropertiesBuffer( properties , properties_len , type , xpath , xpath_len , xpath_size , content , content_len , & CallbackOnReadAllProperties , p ) ;
		if( nret )
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "TravelXmlPropertiesBuffer failed[%d]" , nret )
			DestroyObject( user_data->rt , user_data->out_map_obj ); user_data->out_map_obj = NULL ;
			return nret;
		}
		else
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "TravelXmlPropertiesBuffer ok" )
		}
		
		nret = AddInnerTextToMap( content , content_len , p ) ;
		if( nret )
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "AddInnerTextToMap failed[%d]" , nret )
			DestroyObject( user_data->rt , user_data->out_map_obj ); user_data->out_map_obj = NULL ;
			return nret;
		}
		else
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "AddInnerTextToMap ok" )
		}
		
		nret = CallRuntimeFunction_list_AddTail( user_data->rt , user_data->out_list_obj , user_data->out_map_obj , NULL ) ;
		if( nret )
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "CallRuntimeFunction_list_AddTail failed[%d]" , nret )
			DestroyObject( user_data->rt , user_data->out_map_obj ); user_data->out_map_obj = NULL ;
			return nret;
		}
		else
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( user_data->rt , "CallRuntimeFunction_list_AddTail ok" )
		}
		
		DestroyObject( user_data->rt , user_data->out_map_obj ); user_data->out_map_obj = NULL ;
	}
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_xml_FindAll_string_string_map;
int ZlangInvokeFunction_xml_FindAll_string_string_map( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangObject			*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject			*in2 = GetInputParameterInLocalObjectStack(rt,2) ;
	struct ZlangObject			*in3 = GetInputParameterInLocalObjectStack(rt,3) ;
	struct ZlangObject			*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	char					*xml_str = NULL ;
	char					*tag = NULL ;
	int32_t					tag_len ;
	struct CallbackOnFindAllUserData	user_data ;
	char					xpath_buf[ 4096 ] = "" ;
	int					nret = 0 ;
	
	CallRuntimeFunction_string_GetStringValue( rt , in1 , & xml_str , NULL );
	CallRuntimeFunction_string_GetStringValue( rt , in2 , & tag , & tag_len );
	
	memset( & user_data , 0x00 , sizeof(struct CallbackOnFindAllUserData) );
	user_data.rt = rt ;
	user_data.tag = tag ;
	user_data.tag_len = tag_len ;
	user_data.key_obj = CloneStringObject( rt , NULL ) ;
	if( user_data.key_obj == NULL )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "CloneStringObject failed[%d]" , GetRuntimeErrorNo(rt) )
		return GetRuntimeErrorNo(rt);
	}
	user_data.properties_condition_obj = in3 ;
	user_data.out_list_obj = out1 ;
	
	nret = TravelXmlBuffer( xml_str , xpath_buf , sizeof(xpath_buf) , CallbackOnFindAll , & user_data ) ;
	if( nret )
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_INVOKE_METHOD_RETURN , "TravelXmlBuffer failed[%d]" , nret )
		DestroyObject( rt , user_data.key_obj );
		UnreferObject( rt , out1 );
		return ZLANG_ERROR_INVOKE_METHOD_RETURN;
	}
	
	DestroyObject( rt , user_data.key_obj );
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_xml_TrimTagsAndBlanks_string;
int ZlangInvokeFunction_xml_TrimTagsAndBlanks_string( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangObject		*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject		*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject		*new_obj = NULL ;
	char				**buf = NULL ;
	int32_t				*buf_len = NULL ;
	char				*offset_base = NULL ;
	char				*p = NULL ;
	char				*p2 = NULL ;
	char				seperator_char ;
	int				nret = 0 ;
	
	nret = CloneObject( rt , & new_obj , NULL , in1 ) ;
	if( nret )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "CloneObject failed[%d]" , nret )
		return nret;
	}
	
	CallRuntimeFunction_string_GetDirectPropertiesPtr( rt , new_obj , & buf , NULL , & buf_len );
	if( *buf == NULL )
	{
		UnreferObject( rt , out1 ) ;
		return 0;
	}
	
	offset_base = *buf ;
	for( ; ; )
	{
		p = strchr( offset_base , '<' ) ;
		if( p == NULL )
			break;
		
		p2 = strchr( p+1 , '>' ) ;
		if( p2 == NULL )
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "uncompleted string" )
			DestroyObject( rt , new_obj );
			UnreferObject( rt , out1 ) ;
			return 0;
		}
		
		memmove( p , p2+1 , (*buf_len)-(p2-(*buf)) );
		(*buf_len) -= p2+1 - p ;
		(*buf)[*buf_len] = '\0' ;
		
		offset_base = p ;
	}
	
#define EQ_BLANKS(_p_)			( *(_p_) == ' ' || *(_p_) == '\t' )
#define EQ_NEWLINE(_p_)			( *(_p_) == '\r' || *(_p_) == '\n' )
#define EQ_BLANKS_OR_NEWLINE(_p_)	( EQ_BLANKS(_p_) || EQ_NEWLINE(_p_) )
	offset_base = (*buf) ;
	for( ; ; )
	{
		p = offset_base ;
		if( EQ_BLANKS(p) || EQ_NEWLINE(p) )
		{
			seperator_char = ' ' ;
			for( ; (*p) ; p++ )
			{
				if( EQ_BLANKS(p) )
					;
				else if( EQ_NEWLINE(p) )
					seperator_char = '\n' ;
				else
					break;
			}
			
			if( (*p) || p-offset_base>(offset_base==(*buf)?0:1) )
			{
				memmove( offset_base+(offset_base==(*buf)?0:1) , p , (*buf_len)-(p-(*buf)) );
			}
			if( offset_base != (*buf) )
			{
				offset_base[0] = seperator_char ;
			}
			(*buf_len) -= p - offset_base - (offset_base==(*buf)?0:1) ;
			(*buf)[*buf_len] = '\0' ;
			
			if( offset_base != (*buf) )
			{
				offset_base++;
			}
		}
		else
		{
			for( ; (*p) ; p++ )
			{
				if( ! EQ_NEWLINE(p) && ! EQ_BLANKS(p) )
					;
				else
					break;
			}
			if( (*p) == '\0' )
				break;
			
			offset_base = p ;
		}
	}
	if( EQ_NEWLINE((*buf)+(*buf_len)-1) )
	{
		(*buf_len)--;
		(*buf)[*buf_len] = '\0' ;
	}
	
	ReferObject( rt , out1 , new_obj );
	DestroyObject( rt , new_obj );
	
	return 0;
}

static int ObjectPropertyValueToString( struct ZlangRuntime *rt , struct ZlangObject *o , struct ZlangObject *s , int32_t obj_to_str_style , int32_t depth );

static int ObjectPropertiesToString( struct ZlangRuntime *rt , struct ZlangObject *o , struct ZlangObject *s , int32_t obj_to_str_style , int32_t depth )
{
	struct ZlangObject	*node = NULL ;
	char			*node_name = NULL ;
	int32_t			node_name_len ;
	
	char			**buf = NULL ;
	int32_t			*buf_len = NULL ;
	char			*p = NULL ;
	int32_t			dp ;
	
	int			nret = 0 ;
	
	node = NULL ;
	for( ; ; )
	{
		node = TravelPropertyInObject( rt , o , node ) ;
		if( node == NULL )
			break;
		
		node_name = GetObjectName( node ) ;
		node_name_len = strlen(node_name) ;
		if( IsObjectPropertiesEntityNull( node ) )
		{
			if( obj_to_str_style == OBJECTTOSTRING_STYLE_COMPACT )
			{
				CallRuntimeFunction_string_PrepareBuffer( rt , s , 1 + node_name_len + 3 );
				CallRuntimeFunction_string_GetDirectPropertiesPtr( rt , s , & buf , NULL , & buf_len ); p = *(buf) + *(buf_len) ;
				*(p) = '<' ; p++;
				memcpy( p , node_name , node_name_len ); p += node_name_len ;
				*(p) = ' ' ; p++;
				*(p) = '/' ; p++;
				*(p) = '>' ; p++;
				(*buf_len) += p - (*(buf)+*(buf_len)) ;
			}
			else if( obj_to_str_style == OBJECTTOSTRING_STYLE_INDENT_TAB )
			{
				CallRuntimeFunction_string_PrepareBuffer( rt , s , depth + 1 + node_name_len + 4 );
				CallRuntimeFunction_string_GetDirectPropertiesPtr( rt , s , & buf , NULL , & buf_len ); p = *(buf) + *(buf_len) ;
				for( dp = 0 ; dp < depth ; dp++ ) { *(p) = '\t' ; p++; }
				*(p) = '<' ; p++;
				memcpy( p , node_name , node_name_len ); p += node_name_len ;
				*(p) = ' ' ; p++;
				*(p) = '/' ; p++;
				*(p) = '>' ; p++;
				*(p) = '\n' ; p++;
				(*buf_len) += p - (*(buf)+*(buf_len)) ;
			}
		}
		else if( IsTypeOf( rt , node , GetArrayObjectInRuntimeObjectsHeap(rt) ) || IsTypeOf( rt , node , GetListObjectInRuntimeObjectsHeap(rt) ) || IsTypeOf( rt , node , GetMapObjectInRuntimeObjectsHeap(rt) ) )
		{
			struct ZlangObject	*iterator_obj = NULL ;
			struct ZlangObject	*element = NULL ;
			char			*element_name = NULL ;
			int32_t			element_name_len ;
			
			iterator_obj = CloneIteratorObjectInTmpStack( rt , NULL ) ;
			if( iterator_obj == NULL )
				return GetRuntimeErrorNo(rt);
			
			nret = CallRuntimeFunction_iterator_TravelFirst( rt , iterator_obj , node ) ;
			if( nret )
				return nret;
			
			for( ; ! CallRuntimeFunction_iterator_IsTravelOver( rt , iterator_obj ) ; CallRuntimeFunction_iterator_TravelNext( rt , iterator_obj) )
			{
				nret = CallRuntimeFunction_iterator_GetElement( rt , iterator_obj , & element ) ;
				if( nret )
					break;
				
				if( IsTypeOf( rt , node , GetMapObjectInRuntimeObjectsHeap(rt) ) )
				{
					CallRuntimeFunction_map_Get( rt , node , element , & element );
				}
				
				if( obj_to_str_style == OBJECTTOSTRING_STYLE_COMPACT )
				{
					CallRuntimeFunction_string_PrepareBuffer( rt , s , 1 + node_name_len + 1 );
					CallRuntimeFunction_string_GetDirectPropertiesPtr( rt , s , & buf , NULL , & buf_len ); p = *(buf) + *(buf_len) ;
					*(p) = '<' ; p++;
					memcpy( p , node_name , node_name_len ); p += node_name_len ;
					*(p) = '>' ; p++;
					(*buf_len) += p - (*(buf)+*(buf_len)) ;
				}
				else if( obj_to_str_style == OBJECTTOSTRING_STYLE_INDENT_TAB )
				{
					CallRuntimeFunction_string_PrepareBuffer( rt , s , depth + 1 + node_name_len + 1 );
					CallRuntimeFunction_string_GetDirectPropertiesPtr( rt , s , & buf , NULL , & buf_len ); p = *(buf) + *(buf_len) ;
					for( dp = 0 ; dp < depth ; dp++ ) { *(p) = '\t' ; p++; }
					*(p) = '<' ; p++;
					memcpy( p , node_name , node_name_len ); p += node_name_len ;
					*(p) = '>' ; p++;
					(*buf_len) += p - (*(buf)+*(buf_len)) ;
				}
				
				depth++;
				
				element_name = GetObjectName( element ) ;
				if( element_name )
				{
					element_name_len = strlen(element_name) ;
					
					if( obj_to_str_style == OBJECTTOSTRING_STYLE_COMPACT )
					{
						CallRuntimeFunction_string_PrepareBuffer( rt , s , 1 + element_name_len + 1 );
						CallRuntimeFunction_string_GetDirectPropertiesPtr( rt , s , & buf , NULL , & buf_len ); p = *(buf) + *(buf_len) ;
						*(p) = '<' ; p++;
						memcpy( p , element_name , element_name_len ); p += element_name_len ;
						*(p) = '>' ; p++;
						(*buf_len) += p - (*(buf)+*(buf_len)) ;
					}
					else if( obj_to_str_style == OBJECTTOSTRING_STYLE_INDENT_TAB )
					{
						CallRuntimeFunction_string_PrepareBuffer( rt , s , 1 + depth + 1 + element_name_len + 1 );
						CallRuntimeFunction_string_GetDirectPropertiesPtr( rt , s , & buf , NULL , & buf_len ); p = *(buf) + *(buf_len) ;
						*(p) = '\n' ; p++;
						for( dp = 0 ; dp < depth ; dp++ ) { *(p) = '\t' ; p++; }
						*(p) = '<' ; p++;
						memcpy( p , element_name , element_name_len ); p += element_name_len ;
						*(p) = '>' ; p++;
						(*buf_len) += p - (*(buf)+*(buf_len)) ;
					}
				}
				
				nret = ObjectPropertyValueToString( rt , element , s , obj_to_str_style , depth ) ;
				if( nret )
					return nret;
				
				if( element_name )
				{
					element_name_len = strlen(element_name) ;
					
					if( obj_to_str_style == OBJECTTOSTRING_STYLE_COMPACT )
					{
						CallRuntimeFunction_string_PrepareBuffer( rt , s , 2 + element_name_len + 1 );
						CallRuntimeFunction_string_GetDirectPropertiesPtr( rt , s , & buf , NULL , & buf_len ); p = *(buf) + *(buf_len) ;
						*(p) = '<' ; p++;
						*(p) = '/' ; p++;
						memcpy( p , element_name , element_name_len ); p += element_name_len ;
						*(p) = '>' ; p++;
						(*buf_len) += p - (*(buf)+*(buf_len)) ;
					}
					else if( obj_to_str_style == OBJECTTOSTRING_STYLE_INDENT_TAB )
					{
						CallRuntimeFunction_string_PrepareBuffer( rt , s , 2 + element_name_len + 2 );
						CallRuntimeFunction_string_GetDirectPropertiesPtr( rt , s , & buf , NULL , & buf_len ); p = *(buf) + *(buf_len) ;
						*(p) = '<' ; p++;
						*(p) = '/' ; p++;
						memcpy( p , element_name , element_name_len ); p += element_name_len ;
						*(p) = '>' ; p++;
						*(p) = '\n' ; p++;
						(*buf_len) += p - (*(buf)+*(buf_len)) ;
					}
				}
				
				depth--;
				
				if( element_name )
				{
					if( obj_to_str_style == OBJECTTOSTRING_STYLE_COMPACT )
					{
					}
					else if( obj_to_str_style == OBJECTTOSTRING_STYLE_INDENT_TAB )
					{
						CallRuntimeFunction_string_PrepareBuffer( rt , s , depth );
						CallRuntimeFunction_string_GetDirectPropertiesPtr( rt , s , & buf , NULL , & buf_len ); p = *(buf) + *(buf_len) ;
						for( dp = 0 ; dp < depth ; dp++ ) { *(p) = '\t' ; p++; }
						(*buf_len) += p - (*(buf)+*(buf_len)) ;
					}
				}
				
				if( obj_to_str_style == OBJECTTOSTRING_STYLE_COMPACT )
				{
					CallRuntimeFunction_string_PrepareBuffer( rt , s , 2 + node_name_len + 1 );
					CallRuntimeFunction_string_GetDirectPropertiesPtr( rt , s , & buf , NULL , & buf_len ); p = *(buf) + *(buf_len) ;
					*(p) = '<' ; p++;
					*(p) = '/' ; p++;
					memcpy( p , node_name , node_name_len ); p += node_name_len ;
					*(p) = '>' ; p++;
					(*buf_len) += p - (*(buf)+*(buf_len)) ;
				}
				else if( obj_to_str_style == OBJECTTOSTRING_STYLE_INDENT_TAB )
				{
					CallRuntimeFunction_string_PrepareBuffer( rt , s , 2 + node_name_len + 2 );
					CallRuntimeFunction_string_GetDirectPropertiesPtr( rt , s , & buf , NULL , & buf_len ); p = *(buf) + *(buf_len) ;
					*(p) = '<' ; p++;
					*(p) = '/' ; p++;
					memcpy( p , node_name , node_name_len ); p += node_name_len ;
					*(p) = '>' ; p++;
					*(p) = '\n' ; p++;
					(*buf_len) += p - (*(buf)+*(buf_len)) ;
				}
			}
		}
		else
		{
			if( obj_to_str_style == OBJECTTOSTRING_STYLE_COMPACT )
			{
				CallRuntimeFunction_string_PrepareBuffer( rt , s , 1 + node_name_len + 1 );
				CallRuntimeFunction_string_GetDirectPropertiesPtr( rt , s , & buf , NULL , & buf_len ); p = *(buf) + *(buf_len) ;
				*(p) = '<' ; p++;
				memcpy( p , node_name , node_name_len ); p += node_name_len ;
				*(p) = '>' ; p++;
				(*buf_len) += p - (*(buf)+*(buf_len)) ;
			}
			else if( obj_to_str_style == OBJECTTOSTRING_STYLE_INDENT_TAB )
			{
				CallRuntimeFunction_string_PrepareBuffer( rt , s , depth + 1 + node_name_len + 1 );
				CallRuntimeFunction_string_GetDirectPropertiesPtr( rt , s , & buf , NULL , & buf_len ); p = *(buf) + *(buf_len) ;
				for( dp = 0 ; dp < depth ; dp++ ) { *(p) = '\t' ; p++; }
				*(p) = '<' ; p++;
				memcpy( p , node_name , node_name_len ); p += node_name_len ;
				*(p) = '>' ; p++;
				(*buf_len) += p - (*(buf)+*(buf_len)) ;
			}
			
			nret = ObjectPropertyValueToString( rt , node , s , obj_to_str_style , depth ) ;
			if( nret )
			{
				return nret;
			}
			
			if( obj_to_str_style == OBJECTTOSTRING_STYLE_COMPACT )
			{
				CallRuntimeFunction_string_PrepareBuffer( rt , s , 2 + node_name_len + 1 );
				CallRuntimeFunction_string_GetDirectPropertiesPtr( rt , s , & buf , NULL , & buf_len ); p = *(buf) + *(buf_len) ;
				*(p) = '<' ; p++;
				*(p) = '/' ; p++;
				memcpy( p , node_name , node_name_len ); p += node_name_len ;
				*(p) = '>' ; p++;
				(*buf_len) += p - (*(buf)+*(buf_len)) ;
			}
			else if( obj_to_str_style == OBJECTTOSTRING_STYLE_INDENT_TAB )
			{
				CallRuntimeFunction_string_PrepareBuffer( rt , s , 2 + node_name_len + 2 );
				CallRuntimeFunction_string_GetDirectPropertiesPtr( rt , s , & buf , NULL , & buf_len ); p = *(buf) + *(buf_len) ;
				*(p) = '<' ; p++;
				*(p) = '/' ; p++;
				memcpy( p , node_name , node_name_len ); p += node_name_len ;
				*(p) = '>' ; p++;
				*(p) = '\n' ; p++;
				(*buf_len) += p - (*(buf)+*(buf_len)) ;
			}
		}
	}
	
	return 0;
}

static int ObjectPropertyValueToString( struct ZlangRuntime *rt , struct ZlangObject *o , struct ZlangObject *s , int32_t obj_to_str_style , int32_t depth )
{
	struct ZlangObject	*node = o ;
	
	char			**buf = NULL ;
	int32_t			*buf_len = NULL ;
	char			*p = NULL ;
	int32_t			dp ;
	int32_t			len ;
	
	int16_t			sht ;
	int32_t			i ;
	int64_t			l ;
	float			f ;
	double			d ;
	unsigned char		b ;
	char			*str ;
	int32_t			str_len ;
	
	int			nret = 0 ;
	
	if( IsTypeOf( rt , node , GetBoolObjectInRuntimeObjectsHeap(rt) ) )
	{
		CallRuntimeFunction_bool_GetBoolValue( rt , node , & b );
		
		CallRuntimeFunction_string_PrepareBuffer( rt , s , 7 );
		CallRuntimeFunction_string_GetDirectPropertiesPtr( rt , s , & buf , NULL , & buf_len ); p = *(buf) + *(buf_len) ;
		if( b )
			len = snprintf( p , 7-1 , "true" ) ;
		else
			len = snprintf( p , 7-1 , "false" ) ;
		if( len > 0 ) (*buf_len) += len ;
	}
	else if( IsTypeOf( rt , node , GetStringObjectInRuntimeObjectsHeap(rt) ) )
	{
		CallRuntimeFunction_string_GetStringValue( rt , node , & str , & str_len );
		
		CallRuntimeFunction_string_PrepareBuffer( rt , s , str_len );
		CallRuntimeFunction_string_GetDirectPropertiesPtr( rt , s , & buf , NULL , & buf_len ); p = *(buf) + *(buf_len) ;
		memcpy( p , str , str_len ); p += str_len ;
		(*buf_len) += p - (*(buf)+*(buf_len)) ;
	}
	else if( IsTypeOf( rt , node , GetShortObjectInRuntimeObjectsHeap(rt) ) )
	{
		CallRuntimeFunction_short_GetShortValue( rt , node , & sht );
		
		CallRuntimeFunction_string_PrepareBuffer( rt , s , 20 );
		CallRuntimeFunction_string_GetDirectPropertiesPtr( rt , s , & buf , NULL , & buf_len ); p = *(buf) + *(buf_len) ;
		len = snprintf( p , 20-1 , "%"PRIi16 , i ) ; if( len > 0 ) (*buf_len) += len ;
	}
	else if( IsTypeOf( rt , node , GetIntObjectInRuntimeObjectsHeap(rt) ) )
	{
		CallRuntimeFunction_int_GetIntValue( rt , node , & i );
		
		CallRuntimeFunction_string_PrepareBuffer( rt , s , 40 );
		CallRuntimeFunction_string_GetDirectPropertiesPtr( rt , s , & buf , NULL , & buf_len ); p = *(buf) + *(buf_len) ;
		len = snprintf( p , 40-1 , "%"PRIi32 , i ) ; if( len > 0 ) (*buf_len) += len ;
	}
	else if( IsTypeOf( rt , node , GetLongObjectInRuntimeObjectsHeap(rt) ) )
	{
		CallRuntimeFunction_long_GetLongValue( rt , node , & l );
		
		CallRuntimeFunction_string_PrepareBuffer( rt , s , 80 );
		CallRuntimeFunction_string_GetDirectPropertiesPtr( rt , s , & buf , NULL , & buf_len ); p = *(buf) + *(buf_len) ;
		len = snprintf( p , 80-1 , "%"PRIi64 , l ) ; if( len > 0 ) (*buf_len) += len ;
	}
	else if( IsTypeOf( rt , node , GetFloatObjectInRuntimeObjectsHeap(rt) ) )
	{
		CallRuntimeFunction_float_GetFloatValue( rt , node , & f );
		
		CallRuntimeFunction_string_PrepareBuffer( rt , s , 80 );
		CallRuntimeFunction_string_GetDirectPropertiesPtr( rt , s , & buf , NULL , & buf_len ); p = *(buf) + *(buf_len) ;
		len = snprintf( p , 80-1 , "%f" , f ) ; if( len > 0 ) (*buf_len) += len ;
	}
	else if( IsTypeOf( rt , node , GetDoubleObjectInRuntimeObjectsHeap(rt) ) )
	{
		CallRuntimeFunction_double_GetDoubleValue( rt , node , & d );
		
		CallRuntimeFunction_string_PrepareBuffer( rt , s , 160 );
		CallRuntimeFunction_string_GetDirectPropertiesPtr( rt , s , & buf , NULL , & buf_len ); p = *(buf) + *(buf_len) ;
		len = snprintf( p , 160-1 , "%lf" , d ) ; if( len > 0 ) (*buf_len) += len ;
	}
	else if( IsTypeOf( rt , node , GetArrayObjectInRuntimeObjectsHeap(rt) ) )
	{
	}
	else if( IsTypeOf( rt , node , GetListObjectInRuntimeObjectsHeap(rt) ) )
	{
	}
	else if( IsTypeOf( rt , node , GetMapObjectInRuntimeObjectsHeap(rt) ) )
	{
	}
	else
	{
		if( obj_to_str_style == OBJECTTOSTRING_STYLE_COMPACT )
		{
		}
		else if( obj_to_str_style == OBJECTTOSTRING_STYLE_INDENT_TAB )
		{
			CallRuntimeFunction_string_PrepareBuffer( rt , s , 1 );
			CallRuntimeFunction_string_GetDirectPropertiesPtr( rt , s , & buf , NULL , & buf_len ); p = *(buf) + *(buf_len) ;
			*(p) = '\n' ; p++;
			(*buf_len) += p - (*(buf)+*(buf_len)) ;
		}
		
		nret = ObjectPropertiesToString( rt , node , s , obj_to_str_style , depth+1 ) ;
		if( nret )
			return nret;
		
		if( obj_to_str_style == OBJECTTOSTRING_STYLE_COMPACT )
		{
		}
		else if( obj_to_str_style == OBJECTTOSTRING_STYLE_INDENT_TAB )
		{
			CallRuntimeFunction_string_PrepareBuffer( rt , s , depth );
			CallRuntimeFunction_string_GetDirectPropertiesPtr( rt , s , & buf , NULL , & buf_len ); p = *(buf) + *(buf_len) ;
			for( dp = 0 ; dp < depth ; dp++ ) { *(p) = '\t' ; p++; }
			(*buf_len) += p - (*(buf)+*(buf_len)) ;
		}
	}
	
	return 0;
}

static int ObjectToString( struct ZlangRuntime *rt , struct ZlangObject *o , struct ZlangObject *s , int32_t obj_to_str_style , int32_t depth )
{
	char			*branch_name = NULL ;
	int32_t			branch_name_len ;
	char			**buf = NULL ;
	int32_t			*buf_len = NULL ;
	char			*p = NULL ;
	int			nret = 0 ;
	
	branch_name = GetObjectName(o) ;
	if( branch_name == NULL )
		return -1;
	branch_name_len = strlen(branch_name) ;
	
	if( obj_to_str_style == OBJECTTOSTRING_STYLE_COMPACT )
	{
		CallRuntimeFunction_string_PrepareBuffer( rt , s , 1 + branch_name_len + 1 );
		CallRuntimeFunction_string_GetDirectPropertiesPtr( rt , s , & buf , NULL , & buf_len ); p = *(buf) + *(buf_len) ;
		*(p) = '<' ; p++;
		memcpy( p , branch_name , branch_name_len ); p += branch_name_len ;
		*(p) = '>' ; p++;
		(*buf_len) += p - (*(buf)+*(buf_len)) ;
	}
	else if( obj_to_str_style == OBJECTTOSTRING_STYLE_INDENT_TAB )
	{
		CallRuntimeFunction_string_PrepareBuffer( rt , s , 1 + branch_name_len + 1 + 1 );
		CallRuntimeFunction_string_GetDirectPropertiesPtr( rt , s , & buf , NULL , & buf_len ); p = *(buf) + *(buf_len) ;
		*(p) = '<' ; p++;
		memcpy( p , branch_name , branch_name_len ); p += branch_name_len ;
		*(p) = '>' ; p++;
		*(p) = '\n' ; p++;
		(*buf_len) += p - (*(buf)+*(buf_len)) ;
	}
	
	nret = ObjectPropertiesToString( rt , o , s , obj_to_str_style , depth+1 ) ;
	if( nret )
		return nret;
	
	if( obj_to_str_style == OBJECTTOSTRING_STYLE_COMPACT )
	{
		CallRuntimeFunction_string_PrepareBuffer( rt , s , 1 + 1 + branch_name_len + 1 );
		CallRuntimeFunction_string_GetDirectPropertiesPtr( rt , s , & buf , NULL , & buf_len ); p = *(buf) + *(buf_len) ;
		*(p) = '<' ; p++;
		*(p) = '/' ; p++;
		memcpy( p , branch_name , branch_name_len ); p += branch_name_len ;
		*(p) = '>' ; p++;
		(*buf_len) += p - (*(buf)+*(buf_len)) ;
	}
	else if( obj_to_str_style == OBJECTTOSTRING_STYLE_INDENT_TAB )
	{
		CallRuntimeFunction_string_PrepareBuffer( rt , s , 1 + 1 + branch_name_len + 1 + 1 );
		CallRuntimeFunction_string_GetDirectPropertiesPtr( rt , s , & buf , NULL , & buf_len ); p = *(buf) + *(buf_len) ;
		*(p) = '<' ; p++;
		*(p) = '/' ; p++;
		memcpy( p , branch_name , branch_name_len ); p += branch_name_len ;
		*(p) = '>' ; p++;
		*(p) = '\n' ; p++;
		(*buf_len) += p - (*(buf)+*(buf_len)) ;
	}
	
	CallRuntimeFunction_string_GetDirectPropertiesPtr( rt , s , & buf , NULL , & buf_len ); p = *(buf) + *(buf_len) ;
	*(p) = '\0' ;
	
	return 0;
}

ZlangDirectFunction_xml_ObjectToString xml_ObjectToString;
int xml_ObjectToString( struct ZlangRuntime *rt , struct ZlangObject *obj , struct ZlangObject *o , struct ZlangObject *s , int32_t obj_to_str_style )
{
	return ObjectToString( rt , o , s , obj_to_str_style , 0 );
}

ZlangInvokeFunction ZlangInvokeFunction_xml_ObjectToString_object;
int ZlangInvokeFunction_xml_ObjectToString_object( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangObject		*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject		*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	int				nret = 0 ;
	
	nret = xml_ObjectToString( rt , obj , in1 , out1 , 0 ) ;
	if( nret )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "xml_ObjectToString failed[%d]" , nret )
		
		nret = UnreferObject( rt , out1 ) ;
		if( nret )
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "InitObject failed[%d]" , nret )
			return nret;
		}
		
		return 0;
	}
	
	return 0;
}

ZlangInvokeFunction ZlangInvokeFunction_xml_ObjectToString_object_int;
int ZlangInvokeFunction_xml_ObjectToString_object_int( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangObject		*in1 = GetInputParameterInLocalObjectStack(rt,1) ;
	struct ZlangObject		*in2 = GetInputParameterInLocalObjectStack(rt,2) ;
	struct ZlangObject		*out1 = GetOutputParameterInLocalObjectStack(rt,1) ;
	int32_t				obj_to_str_style ;
	int				nret = 0 ;
	
	CallRuntimeFunction_int_GetIntValue( rt , in2 , & obj_to_str_style );
	
	nret = xml_ObjectToString( rt , obj , in1 , out1 , obj_to_str_style ) ;
	if( nret )
	{
		TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "xml_ObjectToString failed[%d]" , nret )
		
		nret = UnreferObject( rt , out1 ) ;
		if( nret )
		{
			TEST_RUNTIME_DEBUG_THEN_PRINT( rt , "InitObject failed[%d]" , nret )
			return nret;
		}
		
		return 0;
	}
	
	return 0;
}

ZlangCreateDirectPropertyFunction ZlangCreateDirectProperty_xml;
void *ZlangCreateDirectProperty_xml( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_xml	*xml_prop = NULL ;
	
	xml_prop = (struct ZlangDirectProperty_xml *)ZLMALLOC( sizeof(struct ZlangDirectProperty_xml) ) ;
	if( xml_prop == NULL )
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_ALLOC , "alloc memory for entity" )
		return NULL;
	}
	memset( xml_prop , 0x00 , sizeof(struct ZlangDirectProperty_xml) );
	
	return xml_prop;
}

ZlangDestroyDirectPropertyFunction ZlangDestroyDirectProperty_xml;
void ZlangDestroyDirectProperty_xml( struct ZlangRuntime *rt , struct ZlangObject *obj )
{
	struct ZlangDirectProperty_xml	*xml_direct_prop = GetObjectDirectProperty(obj) ;
	
	ZLFREE( xml_direct_prop );
	
	return;
}

ZlangSummarizeDirectPropertySizeFunction ZlangSummarizeDirectPropertySize_xml;
void ZlangSummarizeDirectPropertySize_xml( struct ZlangRuntime *rt , struct ZlangObject *obj , size_t *summarized_obj_size , size_t *summarized_direct_prop_size )
{
	SUMMARIZE_SIZE( summarized_direct_prop_size , sizeof(struct ZlangDirectProperty_xml) )
	return;
}

static struct ZlangDirectFunctions direct_funcs_xml =
	{
		ZLANG_OBJECT_xml , /* char *tpye_name */
		
		ZlangCreateDirectProperty_xml , /* ZlangCreateDirectPropertyFunction *create_entity_func */
		ZlangDestroyDirectProperty_xml , /* ZlangDestroyDirectPropertyFunction *destroy_entity_func */
		
		NULL , /* ZlangFromCharPtrFunction *from_char_ptr_func */
		NULL , /* ZlangToStringFunction *to_string_func */
		NULL , /* ZlangFromDataPtrFunction *from_data_ptr_func */
		NULL , /* ZlangGetDataPtrFunction *get_data_ptr_func */
		
		NULL , /* ZlangOperatorFunction *oper_PLUS_func */
		NULL , /* ZlangOperatorFunction *oper_MINUS_func */
		NULL , /* ZlangOperatorFunction *oper_MUL_func */
		NULL , /* ZlangOperatorFunction *oper_DIV_func */
		NULL , /* ZlangOperatorFunction *oper_MOD_func */
		
		NULL , /* ZlangUnaryOperatorFunction *unaryoper_NEGATIVE_func */
		NULL , /* ZlangUnaryOperatorFunction *unaryoper_NOT_func */
		NULL , /* ZlangUnaryOperatorFunction *unaryoper_BIT_REVERSE_func */
		NULL , /* ZlangUnaryOperatorFunction *unaryoper_PLUS_PLUS_func */
		NULL , /* ZlangUnaryOperatorFunction *unaryoper_MINUS_MINUS_func */
		
		NULL , /* ZlangCompareFunction *comp_EGUAL_func */
		NULL , /* ZlangCompareFunction *comp_NOTEGUAL_func */
		NULL , /* ZlangCompareFunction *comp_LT_func */
		NULL , /* ZlangCompareFunction *comp_LE_func */
		NULL , /* ZlangCompareFunction *comp_GT_func */
		NULL , /* ZlangCompareFunction *comp_GE_func */
		
		NULL , /* ZlangLogicFunction *logic_AND_func */
		NULL , /* ZlangLogicFunction *logic_OR_func */
		
		NULL , /* ZlangLogicFunction *bit_AND_func */
		NULL , /* ZlangLogicFunction *bit_XOR_func */
		NULL , /* ZlangLogicFunction *bit_OR_func */
		NULL , /* ZlangLogicFunction *bit_MOVELEFT_func */
		NULL , /* ZlangLogicFunction *bit_MOVERIGHT_func */
		
		ZlangSummarizeDirectPropertySize_xml , /* ZlangSummarizeDirectPropertySizeFunction *summarize_direct_prop_size_func */
	} ;

ZlangImportObjectFunction ZlangImportObject_xml;
struct ZlangObject *ZlangImportObject_xml( struct ZlangRuntime *rt )
{
	struct ZlangObject	*obj = NULL ;
	struct ZlangObject	*prop = NULL ;
	struct ZlangFunction	*func = NULL ;
	int			nret = 0 ;
	
	nret = ImportObject( rt , & obj , ZLANG_OBJECT_xml , & direct_funcs_xml , sizeof(struct ZlangDirectFunctions) , NULL ) ;
	if( nret )
	{
		SET_RUNTIME_ERROR( rt , RUNTIME_ERROR , ZLANG_ERROR_LINK_FUNC_TO_ENTITY , "import object to global objects heap" )
		return NULL;
	}
	
	/* int xml.STRINGTOOBJECT_OPTION_LESSSTRICT */
	prop = AddPropertyInObject( rt , obj , QueryObjectByObjectName(rt,"int") , "STRINGTOOBJECT_OPTION_LESSSTRICT") ;
	if( prop == NULL )
		return NULL;
	CallRuntimeFunction_int_SetIntValue( rt , prop , STRINGTOOBJECT_OPTION_LESSSTRICT );
	SetConstantObject( prop );
	
	/* int xml.OBJECTTOSTRING_STYLE_COMPACT */
	prop = AddPropertyInObject( rt , obj , QueryObjectByObjectName(rt,"int") , "OBJECTTOSTRING_STYLE_COMPACT") ;
	if( prop == NULL )
		return NULL;
	CallRuntimeFunction_int_SetIntValue( rt , prop , OBJECTTOSTRING_STYLE_COMPACT );
	SetConstantObject( prop );
	
	/* int xml.OBJECTTOSTRING_STYLE_INDENT_TAB */
	prop = AddPropertyInObject( rt , obj , QueryObjectByObjectName(rt,"int") , "OBJECTTOSTRING_STYLE_INDENT_TAB") ;
	if( prop == NULL )
		return NULL;
	CallRuntimeFunction_int_SetIntValue( rt , prop , OBJECTTOSTRING_STYLE_INDENT_TAB );
	SetConstantObject( prop );
	
	/* xml.StringToObject() */
	func = AddFunctionAndParametersInObject( rt , obj , "StringToObject" , "StringToObject(string)" , ZlangInvokeFunction_xml_StringToObject_string , ZLANG_OBJECT_object , ZLANG_OBJECT_string,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* xml.StringToEntityObject() */
	func = AddFunctionAndParametersInObject( rt , obj , "StringToEntityObject" , "StringToEntityObject(string,object)" , ZlangInvokeFunction_xml_StringToEntityObject_string_object , ZLANG_OBJECT_bool , ZLANG_OBJECT_string,NULL , ZLANG_OBJECT_object,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* xml.SignSpecialHtmlTags() */
	func = AddFunctionAndParametersInObject( rt , obj , "SignSpecialHtmlTags" , "SignSpecialHtmlTags()" , ZlangInvokeFunction_xml_SignSpecialHtmlTags , ZLANG_OBJECT_void , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* xml.Xpath() */
	func = AddFunctionAndParametersInObject( rt , obj , "Xpath" , "Xpath(string,string)" , ZlangInvokeFunction_xml_Xpath_string_string , ZLANG_OBJECT_string , ZLANG_OBJECT_string,NULL , ZLANG_OBJECT_string,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* xml.Xnode() */
	func = AddFunctionAndParametersInObject( rt , obj , "Xnode" , "Xnode(string,string)" , ZlangInvokeFunction_xml_Xnode_string_string , ZLANG_OBJECT_string , ZLANG_OBJECT_string,NULL , ZLANG_OBJECT_string,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* xml.FindAll() */
	func = AddFunctionAndParametersInObject( rt , obj , "FindAll" , "FindAll(string,string,map)" , ZlangInvokeFunction_xml_FindAll_string_string_map , ZLANG_OBJECT_list , ZLANG_OBJECT_string,NULL , ZLANG_OBJECT_string,NULL , ZLANG_OBJECT_map,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* xml.TrimTagsAndBlanks() */
	func = AddFunctionAndParametersInObject( rt , obj , "TrimTagsAndBlanks" , "TrimTagsAndBlanks(string)" , ZlangInvokeFunction_xml_TrimTagsAndBlanks_string , ZLANG_OBJECT_string , ZLANG_OBJECT_string,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* xml.ObjectToString() */
	func = AddFunctionAndParametersInObject( rt , obj , "ObjectToString" , "ObjectToString(object)" , ZlangInvokeFunction_xml_ObjectToString_object , ZLANG_OBJECT_string , ZLANG_OBJECT_object,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	/* xml.ObjectToString() */
	func = AddFunctionAndParametersInObject( rt , obj , "ObjectToString" , "ObjectToString(object,int)" , ZlangInvokeFunction_xml_ObjectToString_object_int , ZLANG_OBJECT_string , ZLANG_OBJECT_object,NULL , ZLANG_OBJECT_int,NULL , NULL ) ;
	if( func == NULL )
		return NULL;
	
	SetRuntimeFunction_xml_StringToObject( rt , xml_StringToObject );
	SetRuntimeFunction_xml_ObjectToString( rt , xml_ObjectToString );
	
	return obj ;
}

